package name.cyrax.red.jpv.api.funcs.info;

public abstract class FunctorMethod
{
	public abstract FunctorMethodKind kind();
	public abstract ValueType result();
	public abstract Class<?> target();
	public abstract String name();
	public abstract ValueType param(int index);
	
	public static FunctorMethod newCast(final ValueType result, final ValueType from) {
		return new FunctorMethod() {
			@Override public ValueType param(int index) {
				return index == 0 ? from : null;
			}			
			@Override public String name() {
				return null;
			}
			@Override public FunctorMethodKind kind() {
				return FunctorMethodKind.CAST;
			}
			@Override public ValueType result() {
				return result;
			}
			@Override public Class<?> target() {
				return null;
			}
		};
	}

	public static FunctorMethod newArrayGet(final ValueType result) {
		return new FunctorMethod() {
			@Override public ValueType param(int index) {
				return null;
			}			
			@Override public String name() {
				return null;
			}
			@Override public FunctorMethodKind kind() {
				return FunctorMethodKind.ARRAY_GET;
			}
			@Override public ValueType result() {
				return result;
			}
			@Override public Class<?> target() {
				return Object[].class;
			}
		};
	}

	public static FunctorMethod newIndexGet(final Class<?> target, final String name, 
			final ValueType result) 
	{
		return new FunctorMethod() {
			@Override public ValueType param(int index) {
				return null;
			}			
			@Override public String name() {
				return name;
			}
			@Override public FunctorMethodKind kind() {
				return FunctorMethodKind.INDEX_GET;
			}
			@Override public ValueType result() {
				return result;
			}
			@Override public Class<?> target() {
				return target;
			}
		};
	}

	public static FunctorMethod newMethod(final Class<?> target, final String name, 
			final ValueType result) 
	{
		return new FunctorMethod() {
			@Override public ValueType param(int index) {
				return null;
			}			
			@Override public String name() {
				return name;
			}
			@Override public FunctorMethodKind kind() {
				return FunctorMethodKind.VIRTUAL;
			}
			@Override public ValueType result() {
				return result;
			}
			@Override public Class<?> target() {
				return target;
			}
		};
	}

	public static FunctorMethod newMethod(final Class<?> target, final String name, 
			final ValueType result, final ValueType param0) 
	{
		return new FunctorMethod() {
			@Override public ValueType param(int index) {
				return index == 0 ? param0 : null;
			}			
			@Override public String name() {
				return name;
			}
			@Override public FunctorMethodKind kind() {
				return FunctorMethodKind.VIRTUAL;
			}
			@Override public ValueType result() {
				return result;
			}
			@Override public Class<?> target() {
				return target;
			}
		};
	}

	public static FunctorMethod newMethod(final Class<?> target, final String name, 
			final ValueType result, final ValueType param0, final ValueType param1) {
		return new FunctorMethod() {
			@Override public ValueType param(int index) {
				return index == 0 ? param0 : (index == 1 ? param1 : null);
			}			
			@Override public String name() {
				return name;
			}
			@Override public FunctorMethodKind kind() {
				return FunctorMethodKind.VIRTUAL;
			}
			@Override public ValueType result() {
				return result;
			}
			@Override public Class<?> target() {
				return target;
			}
		};
	}
	
//	@Override public String toString()
//	{
//		return "(" + result() + ") " + name();
//	}
}
